package com.ssm.base.exception;

import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.util.BeanUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/7/7.
 */
public class GlobalExceptionResolver implements HandlerExceptionResolver {
    protected final Log logger = LogFactory.getLog(getClass());
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        MappingJackson2JsonView view = new MappingJackson2JsonView();
        view.setPrettyPrint(true);
        ModelAndView modelAndView = new ModelAndView(view);
        Map<String,Object> map = modelAndView.getModelMap();
        map.put("code","-9999");
        map.put("message","服务器异常");
        PropertyDescriptor[]  descriptors =  BeanUtils.getPropertyDescriptors(ex.getClass());

        List<String> includeProperties = new ArrayList<>();
        includeProperties.add("message");
        includeProperties.add("code");
        includeProperties.add("error");

        for(PropertyDescriptor descriptor:descriptors){
            String name = descriptor.getName();
            if(includeProperties.contains(name)){
                Method method = descriptor.getReadMethod();
                if(method!=null){
                    try {
                        boolean readAble = Modifier.isPublic(method.getDeclaringClass().getModifiers());
                        if (readAble) {
                            Object value = method.invoke(ex);
                            if(map.containsKey(name)){
                                if(value!=null) map.put(name,value);
                            }
                            else{
                                map.put(name,value);
                            }
                        }
                    }
                    catch (Throwable e) {
                        logger.debug(e.getMessage());
                    }
                }
            }
        }
        return modelAndView;
    }
}
